package me.keiwu.pub.util.redis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

import java.util.Set;

/**
 * Created by kei on 12/09/2017.
 */
@Component
public class RedisUtil {

    private static final Logger logger = LoggerFactory.getLogger(RedisUtil.class);


    @Autowired
    private ShardedJedisPool shardedJedisPool;



    public String get(String key) {
        ShardedJedis resource = null;
        try {
            resource = shardedJedisPool.getResource();
            return resource.get(key);
        } catch (Exception e) {
            logger.error("redisUtil get error: ", e);
            return null;
        } finally {
            if (resource != null) {
                resource.close();
            }
        }
    }

    public String set(String key, String value) {
        return this.set(key, value, null);
    }

    public String set(String key, String value, Integer expiredSecs) {
        ShardedJedis resource = null;
        try {
            resource = shardedJedisPool.getResource();
            String result = resource.set(key, value);
            if (expiredSecs != null) {
                resource.expire(key, expiredSecs);
            }
            return result;
        } catch (Exception e) {
            logger.error("redisUtil set error: ", e);
            return null;
        } finally {
            if (resource != null) {
                resource.close();
            }
        }

    }


    public Long incr(String key) {
        ShardedJedis resource = null;
        try {
            resource = shardedJedisPool.getResource();
            return resource.incr(key);
        } catch (Exception e) {
            logger.error("redisUtil incr error: ", e);
            return null;
        } finally {
            if (resource != null) {
                resource.close();
            }
        }
    }

    public Long incrBy(String key, long increment) {
        ShardedJedis resource = null;
        try {
            resource = shardedJedisPool.getResource();
            return resource.incrBy(key, increment);
        } catch (Exception e) {
            logger.error("redisUtil incrBy error: ", e);
            return null;
        } finally {
            if (resource != null) {
                resource.close();
            }
        }
    }


    public Long del(String key) {
        ShardedJedis resource = null;
        try {
            resource = shardedJedisPool.getResource();
            return resource.del(key);
        } catch (Exception e) {
            logger.error("redisUtil del error: ", e);
            return null;
        } finally {
            if (resource != null) {
                resource.close();
            }
        }
    }


    public Long zadd(String key, double score, String member) {
        ShardedJedis resource = null;
        try {
            resource = shardedJedisPool.getResource();
            return resource.zadd(key, score, member);
        } catch (Exception e) {
            logger.error("redisUtil zadd error: ", e);
            return null;
        } finally {
            if (resource != null) {
                resource.close();
            }
        }
    }

    public Long zrank(String key, String member) {
        ShardedJedis resource = null;
        try {
            resource = shardedJedisPool.getResource();
            return resource.zrank(key, member);
        } catch (Exception e) {
            logger.error("redisUtil zrank error: ", e);
            return null;
        } finally {
            if (resource != null) {
                resource.close();
            }
        }
    }

    public Long zrevrank(String key, String member) {
        ShardedJedis resource = null;
        try {
            resource = shardedJedisPool.getResource();
            return resource.zrevrank(key, member);
        } catch (Exception e) {
            logger.error("redisUtil zrevrank error: ", e);
            return null;
        } finally {
            if (resource != null) {
                resource.close();
            }
        }
    }

    public Set<String> zrange(String key, long start, long end) {
        ShardedJedis resource = null;
        try {
            resource = shardedJedisPool.getResource();
            return resource.zrange(key, start, end);
        } catch (Exception e) {
            logger.error("redisUtil zrange error: ", e);
            return null;
        } finally {
            if (resource != null) {
                resource.close();
            }
        }
    }

    public Set<String> zrevrange(String key, long start, long end) {
        ShardedJedis resource = null;
        try {
            resource = shardedJedisPool.getResource();
            return resource.zrevrange(key, start, end);
        } catch (Exception e) {
            logger.error("redisUtil zrevrange error: ", e);
            return null;
        } finally {
            if (resource != null) {
                resource.close();
            }
        }
    }

    public Double zscore(String key, String member) {
        ShardedJedis resource = null;
        try {
            resource = shardedJedisPool.getResource();
            return resource.zscore(key, member);
        } catch (Exception e) {
            logger.error("redisUtil zscore error: ", e);
            return null;
        } finally {
            if (resource != null) {
                resource.close();
            }
        }
    }






    //===========================================================
    //===================== shard operation =====================
    //===========================================================
    public String shardGet(String shardKey, String key) {
        Jedis jedis = null;
        try {
            jedis = shardedJedisPool.getResource().getShard(shardKey);
            return jedis.get(key);
        } catch (Exception e) {
            logger.error("redisUtil shardGet error: ", e);
            return null;
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }

    public String shardSet(String shardKey, String key, String value, Integer expiredSecs) {
        Jedis jedis = null;
        try {
            jedis = shardedJedisPool.getResource().getShard(shardKey);
            String result = jedis.set(key, value);
            if (expiredSecs != null) {
                jedis.expire(key, expiredSecs);
            }
            return result;
        } catch (Exception e) {
            logger.error("redisUtil shardSet error: ", e);
            return null;
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }

    }

    public Long shardDel(String shardKey, String key) {
        Jedis jedis = null;
        try {
            jedis = shardedJedisPool.getResource().getShard(shardKey);
            return jedis.del(key);
        } catch (Exception e) {
            logger.error("redisUtil shardDel error: ", e);
            return null;
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }

    public Set<String> shardKeys(String sharedKey, String pattern) {
        Jedis jedis = null;
        try {
            jedis = shardedJedisPool.getResource().getShard(sharedKey);
            return jedis.keys(pattern);
        } catch (Exception e) {
            logger.error("redisUtil shardKeys error: ", e);
            return null;
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }

}
